package com.jwd.avmanager.client;

import com.jwd.avmanager.client.inter.EventListener;
import com.jwd.avmanager.client.inter.EventListenerGps;
import com.jwd.avmanager.client.inter.EventListenerGroup;
import com.jwd.avmanager.entity.MsgPacket;
import com.jwd.avmanager.util.DebugLogger;

import java.io.*;
import java.net.Socket;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;

/**
 * 客户端的信令协议封装
 */
public class ProtocolClient {

    public static final int ERR_PARAM_INVALID = -2;//参数不合法
    public static final int ERR_REPEAT_OPERATE = -3;//不允许重复操作
    public static final int ERR_SOCKET_EXCEPTION = -3;//socket抛异常
    public static final int HEART_PERIOD = 30;//心跳周期
    private static Socket socket;
    private static final String IP = "127.0.0.1";
    private static final int PORT = 9898;
    private static final int STATE_CONNECTING = 1001;//正在连接
    private static final int STATE_CONNECTED = 1001;//连接完成
    private static final int STATE_NOT_CONNECTED = 1003;//未连接
    private int currentState = STATE_NOT_CONNECTED;//当前状态
    //    private boolean isConnecting;//正在连接
//    private boolean isConnected;
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private EventListener<Boolean> loginListener;//登录状态监听
    private EventListenerGps<Void> eventListenerGps;//登录状态监听
    private EventListenerGroup<String> eventListenerGroup;//登录状态监听
    private EventListener<Void> connListener;//连接状态监听


    private Timer timer;//计时器
    private TimerTask heartTask;//心跳任务

    public ProtocolClient() {
        timer = new Timer();
    }

    /**
     * 向服务器发送登录信令
     * typedef struct tagDevice_Param
     * {
     * tMSG_HEADER hdr ;
     * char DeviceNo[16];   //16个字节，设备编号
     * char UserNo[16];    //16个字节，用户编号
     * char IMEI[30];     // 30 byte,设备的IMEI码
     * } tDevice_Param ;
     *
     * @param deviceNo 设备id
     * @param userNo   用户id
     * @param listener 结果回调
     */
    public void login(String deviceNo, String userNo, EventListener<Boolean> listener) {
        loginListener = listener;

        //校验参数
        if (deviceNo == null || userNo == null) {
            listener.onError(ERR_PARAM_INVALID);
            return;
        }
        //正则校验
        String pattern = "^\\w{4,8}";
        boolean deviceNoMatch = Pattern.matches(pattern, deviceNo);
        boolean userNoMatch = Pattern.matches(pattern, userNo);
        if (!deviceNoMatch || !userNoMatch) {
            //参数不合法
            loginListener.onError(ERR_PARAM_INVALID);
            return;
        }
        loginListener.onSuccess(true);
        //发送登录指令
        String imei = "12345678";//android 根据实际情况生成
        MsgPacket loginPacket = MessageFactory.getLoginPacket(deviceNo, userNo, imei);


        sendMessage(loginPacket.getBytes());
    }


    public void gps(EventListenerGps<Void> listener) {
        eventListenerGps = listener;


        MsgPacket loginPacket = MessageFactory.getGpsPacket();
        sendMessage(loginPacket.getBytes());
    }

    public void uploadGPS() {
        MsgPacket msgPacket = MessageFactory.setGPS(666);
        sendMessage(msgPacket.getBytes());
    }

    public void tagIMEI() {
        char[] a = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 's', 'k'};
        MsgPacket msgPacket = MessageFactory.getIE(a);
        sendMessage(msgPacket.getBytes());
    }


    /**
     * 开始心跳保活
     */
    public void startHeartbeat() {
        if (heartTask != null) {
            heartTask.cancel();
            heartTask = null;
        }
        heartTask = new HeartbeatTask();
        //10s后发送第一个心跳包，后面每隔一个周期发一次
        timer.schedule(heartTask, 10 * 1000, HEART_PERIOD * 1000);
    }

    /**
     * 获取对讲组内通话人员列表
     */
    public void getTalkbackCall() {
        MsgPacket loginPacket = MessageFactory.getTalkbackCallT("77s77s77");
        sendMessage(loginPacket.getBytes());
    }

    /**
     * 请求组
     */
    public void getUserF() {
        MsgPacket loginPacket = MessageFactory.getUser("666666");
        sendMessage(loginPacket.getBytes());
    }

    /**
     * 请求组
     */
    public void getGroupF(EventListenerGroup<String> listener) {
        eventListenerGroup = listener;
        listener.onSuccess("成功");
        MsgPacket loginPacket = MessageFactory.getGroup("135");

        sendMessage(loginPacket.getBytes());
    }

    /**
     * 8
     * 连接服务器
     *
     * @param listener 结果回调
     */
    public void connectToServer(EventListener<Void> listener) {
        connListener = listener;
        if (currentState != STATE_CONNECTING) {
            executorService.execute(new ConnectTask(listener));
        } else {
            //正在连接中，不让重复操作
            if (listener != null) {
                listener.onError(ERR_REPEAT_OPERATE);
            }
        }
    }

    /**
     * 通过tcp发送消息
     *
     * @param message
     */
    private void sendMessage(byte[] message) {
        if (message == null) return;
        try {
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(message);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            connListener.onError(ERR_SOCKET_EXCEPTION);

        }
    }

    //连接服务器的任务
    class ConnectTask implements Runnable {


        public ConnectTask(EventListener<Void> listener) {

        }

        @Override
        public void run() {
            try {
                currentState = STATE_CONNECTING;//当前处于正在连接状态
                socket = new Socket(IP, PORT);
                currentState = STATE_CONNECTED;//连接成功
                executorService.execute(new ReceiveTask());//启动接收线程
                if (connListener != null) {
                    connListener.onSuccess(null);
                }
            } catch (IOException e) {
                e.printStackTrace();
                currentState = STATE_NOT_CONNECTED;//未连接
                socket = null;
                if (connListener != null) {
                    connListener.onError(ERR_SOCKET_EXCEPTION);
                }
            }
        }
    }

    /**
     * 接收服务器消息
     */
    class ReceiveTask implements Runnable {

        @Override
        public void run() {
            while (currentState == STATE_CONNECTED) {
                try {
                    DebugLogger.info("等待数据");
                    InputStream inputStream = socket.getInputStream();
                    byte[] buffer = new byte[512];
                    int read = inputStream.read(buffer);
                    byte[] receive = new byte[read];
                    System.arraycopy(buffer, 0, receive, 0, read);
                    DebugLogger.info("服务器数据：" + Arrays.toString(receive));

                } catch (IOException e) {
                    currentState = STATE_NOT_CONNECTED;
                    e.printStackTrace();
                }
            }
        }
    }

    //发送心跳包
    private void sendHeartbeat() {
        MsgPacket heartbeatPacket = MessageFactory.getHeartbeatPacket();
        sendMessage(heartbeatPacket.getBytes());
    }

    /**
     * 心跳任务
     */
    class HeartbeatTask extends TimerTask {


        @Override
        public void run() {
            sendHeartbeat();
        }
    }

    /**
     * 释放
     */
    public void release() {
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        currentState = STATE_NOT_CONNECTED;
        executorService.shutdownNow();
    }
}
